﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace VsTortoiseSVN
{
    public static class PathHelper
    {
        private static StringBuilder _tempBuffer = new StringBuilder(Win32.MAX_PATH);

        /// <summary>
        /// The ToLongPathNameToShortPathName function retrieves the short path form of a specified long input path
        /// </summary>
        /// <param name="longName">The long name path</param>
        /// <returns>A short name path string</returns>
        public static string GetShortPathName(string longPath)
        {
            if (String.IsNullOrEmpty(longPath))
                return longPath;

            Win32.GetShortPathName(longPath, _tempBuffer, (uint)_tempBuffer.Capacity);
            return _tempBuffer.ToString();
        }

        /// <summary>
        /// Converts a short path to a long path.
        /// </summary>
        /// <param name="shortPath">A path that may contain short path elements (~1).</param>
        /// <returns>The long path.  Null or empty if the input is null or empty.</returns>
        public static string GetLongPathName(string shortPath)
        {
            if (String.IsNullOrEmpty(shortPath))
                return shortPath;

            Win32.GetLongPathName(shortPath, _tempBuffer, _tempBuffer.Capacity);
            return _tempBuffer.ToString();
        }

        /// <summary>
        /// Gets whether sub is a sub-directory of root.
        /// </summary>
        public static bool IsSubDirectory(string root, string sub)
        {
            if (sub.IndexOf(root + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) > -1)
                return true;

            if (sub.IndexOf(root + Path.AltDirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) > -1)
                return true;

            return false;
        }

        /// <summary>
        /// Removes  sub-directories from directories.
        /// </summary>
        public static void RemoveSubDirectories(List<string> directories)
        {
            List<string> source = new List<string>(directories);
            RemoveSubDirectories(directories, source);
        }

        /// <summary>
        /// Removes sub-directories from source and stores the
        /// result of the operation in dest.
        /// </summary>
        public static void RemoveSubDirectories(List<string> dest, ICollection<string> source)
        {
            dest.Clear();
            dest.AddRange(source);

            for (int i = dest.Count-1; i >= 0; --i)
            {
                for (int j = i - 1; j >= 0; --j)
                {
                    if (string.Compare(dest[j], dest[i], true) == 0)
                    {
                        dest.RemoveAt(i);
                        break;
                    }

                    if (IsSubDirectory(dest[j], dest[i]))
                    {
                        dest.RemoveAt(i);
                        break;
                    }

                    if (IsSubDirectory(dest[i], dest[j]))
                    {
                        dest.RemoveAt(j);
                        break;
                    }
                }
            }
        }
    }
}
